#include "NewThing.h"
#include <SDL/SDL_ttf.h>

NewThing::NewThing()
{
	SDL_Init(SDL_INIT_EVERYTHING);
	m_screen= SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE); 
	SDL_WM_SetCaption("Planetz", NULL);

	TTF_Init();	

	srand(SDL_GetTicks()); //seed
	
	m_game = Game(GC_NUM_PLAYERS);
	m_space = Space(&m_game);

	moveCamera(640/2, 480/2);
	m_camera_scale = GC_STARTING_SCALE + 2 * GC_SCALE_STEP;

	newGame();

	m_run = true;

	for(int i = 0; i < 2000; i++)
	{
		m_buttons[i] = false;
	}
}

NewThing::~NewThing()
{
	//SDL_FreeSurface(x);

	SDL_Quit();
}

void NewThing::newGame()
{
	m_space.clear();
	m_game.restart();
	addDefaultPlanets();
	//m_boom.clear();
}

void NewThing::Run()
{
	SDL_Event event;

	while(m_run)
	{
		SDL_Delay(15);

		while(SDL_PollEvent(&event))
		{
			switch (event.type)
			{
				case SDL_QUIT:
					m_run = false;
					break;
				case SDL_KEYDOWN:
					m_buttons[event.key.keysym.sym] = true;
					break;
				case SDL_KEYUP:
					m_buttons[event.key.keysym.sym] = false;
					break;
			}
		}

		//do drawing stuff here

		SDL_FillRect(m_screen, NULL, SDL_MapRGB(m_screen->format, 0, 0, 0));
		drawObjects();
		drawWidgets();

		SDL_Flip(m_screen);

		PokeYou();
	}

}

bool NewThing::running()
{
	return m_run;
}

void NewThing::stop()
{
	m_run = false;
}

Space* NewThing::getSpace()
{
	return &m_space;
}

void NewThing::PokeYou()
{
	if (m_buttons[SDLK_UP])
		moveCameraIP(0,10);
	if (m_buttons[SDLK_DOWN])
		moveCameraIP(0,-10);
	if (m_buttons[SDLK_LEFT])
		moveCameraIP(10,0);
	if (m_buttons[SDLK_RIGHT])
		moveCameraIP(-10,0);
	//Player1 controls:
	if (m_buttons[SDLK_d])
		m_game.getPlayer(0)->aimIP(-GC_TURN_SPEED);

	if (m_buttons[SDLK_f])
		m_game.getPlayer(0)->aimIP(GC_TURN_SPEED);
	if (m_buttons[SDLK_g])
		{
			Player *p = m_game.getPlayer(0);
			if(p != NULL)
			{
				fire(p);
			}
		}
	//Player2 controls:
	if (m_buttons[SDLK_j])
		m_game.getPlayer(1)->aimIP(-GC_TURN_SPEED);

	if (m_buttons[SDLK_k])
		m_game.getPlayer(1)->aimIP(GC_TURN_SPEED);
	if (m_buttons[SDLK_l])
		{
			Player *p = m_game.getPlayer(1);
			if(p != NULL)
			{
				fire(p);
			}
		}
}

void NewThing::drawObjects()
{
	m_space.Lock();
	std::vector<Object*> obj = m_space.getObjects();
	m_space.Unlock();

	for(unsigned int i = 0; i < obj.size(); i++)
	{
		drawObject(obj[i]);
	}
}

void NewThing::drawObject(Object* p_obj)
{
	//print_me(p_obj->getName().c_str());

	Vector2 position = p_obj->getPosition();
	double radius = p_obj->getRadius() * ((double)GC_STARTING_SCALE)/((double)m_camera_scale);
	double x = position.getX()/m_camera_scale+m_camera_x;
	double y = position.getY()/m_camera_scale+m_camera_y;

	color col = p_obj->getColor();

	if (p_obj->getType() == PLANET)
	{
		Planet* planet = (Planet*)p_obj;		

		Player *player = NULL;
		player = m_game.getPlayerFromObject(p_obj);

		if(player != NULL)
		{
			//aim
			Vector2 aim = player->getAim();
			aim = aim * radius * 2;
			lineRGBA(m_screen, x, y, x+aim.getX(), y+aim.getY(), player->getRed(),  player->getGreen(),  player->getBlue(), 255);
	
			//mp bar
			lineRGBA(m_screen, x-10, y-radius*2-3, x-10+20, y-radius*2-3, 0, 0, 100, 255 );
			lineRGBA(m_screen, x-10, y-radius*2-3, x-10+20.0*(double)planet->getMana()/GC_PLANET_MANA, y-radius*2-3, 0, 0, 255, 255 );
		}
	}

	if (p_obj->getType() != MISSILE)
	{
		filledEllipseRGBA(m_screen, x, y, radius, radius, col.red, col.green, col.blue, col.alpha);
		//hp bar
		lineRGBA(m_screen, x-10, y-radius*2-5, x-10+20, y-radius*2-5, 100, 0, 0, 255 );

		double max_health=0;
		if(p_obj->getType() == PLANET)
			max_health = GC_PLANET_HEALTH;
		else
			max_health = GC_STAR_HEALTH;
		
		double h = (double)p_obj->getHealth()/max_health;

		//NamedObject* n = (NamedObject*)p_obj;
		//std::cout << n->getName() << ": " << h*100 << "% health\n";

		lineRGBA(m_screen, x-10, y-radius*2-5, x-10+20.0*h, y-radius*2-5, 255, 0, 0, 255);
	} else {
		Missile* missile = (Missile*)p_obj;
		Vector2 d = missile->getDirection();
		d = d * 1.5;

		lineRGBA(m_screen, x-d.getX(), y-d.getY(), x+d.getX(), y+d.getY(), col.red, col.green, col.blue, col.alpha);
	}

	if (p_obj->getType() == PLANET)
	{
		Player *player = NULL;
		player = m_game.getPlayerFromObject(p_obj);

		if(player != NULL)
		{
			//border
			ellipseRGBA(m_screen, x, y, radius, radius, player->getRed(), player->getGreen(), player->getBlue(), 255 );
		}
	}
}

void NewThing::drawWidgets()
{
	m_space.Lock();
	std::list<Widget*> widgets = m_space.getWidgets();
	m_space.Unlock();

	std::list<Widget*>::iterator itr;
	for(itr = widgets.begin(); itr != widgets.end(); itr++)
	{
		if ((*itr)->getType() == DAMAGEWIDGET)
			drawDamageWidget((DamageWidget*)(*itr));
		else
			drawExplosion((ExplosionEffect*)(*itr));
	}
}

void NewThing::drawDamageWidget(DamageWidget* p_widget)
{
/*
	color col = p_widget->getColor();
	SDL_Color c={col.red,col.green,col.blue};

	char* str;
	asprintf(&str, "%d",  p_widget->getDamageDone());

	TTF_Font *font = TTF_OpenFont("DejaVuSans.ttf", 16); //todo: error check

	SDL_Surface* text=TTF_RenderText_Blended(font,str,c);


	Vector2 position = p_widget->getPosition();
	double x = position.getX()/m_camera_scale+m_camera_x;
	double y = position.getY()/m_camera_scale+m_camera_y;

	SDL_Rect rect;
	rect.x = x;
	rect.y = y;

    	SDL_BlitSurface(text,NULL,m_screen,&rect);    

    	SDL_FreeSurface(text);
	free(str); */
}

void NewThing::drawExplosion(ExplosionEffect* p_explosion)
{
	ExplosionEffect* p_obj = p_explosion;

	Vector2 position = p_obj->getPosition();
	double radius = p_obj->getRadius() * ((double)GC_STARTING_SCALE)/((double)m_camera_scale);
	double x = position.getX()/m_camera_scale+m_camera_x;
	double y = position.getY()/m_camera_scale+m_camera_y;

	color col = p_obj->getColor();

	filledEllipseRGBA(m_screen, x, y, radius, radius, col.red, col.green, col.blue, col.alpha);
}

void NewThing::fire(Player* p_player)
{
	Planet* planet = (Planet*)p_player->getPlanet();

	if (planet->useMana(GC_MISSILE_MANA_COST))
	{
		std::cout << "Creating missile with " << planet->getRadius()*GC_MISSILE_BLOW_DAMAGE << " damage" << std::endl;
		//PlaySound("skjut.wav", NULL, SND_ASYNC); 
		Object *missile = new Missile(
			planet->getRadius()*GC_MISSILE_BLOW_DAMAGE,
			p_player->getPlanet()->getPosition(),
			p_player->getPlanet()->getVelocity()+Vector2(p_player->getAim()*GC_MISSILE_SPEED)
		);

		m_space.addObject(missile);
	}
}



void NewThing::moveCamera(int p_x, int p_y)
{
	m_camera_x = p_x;
	m_camera_y = p_y;
}

void NewThing::moveCameraIP(int p_x, int p_y)
{
	m_camera_x += p_x;
	m_camera_y += p_y;
}




void NewThing::addDefaultPlanets()
{
	Object* kaka = NULL; 
	Object* sol = NULL;
	Player* player = NULL; //temp



	//sol
	sol = new NamedObject(
		"Sol",
		STAR,
		color(255,255,0,255),
		1.9891e30,
		25,
		Vector2(0e9,0e9),
		Vector2(0,0));
	m_space.addObject(sol);

	//mercury
	kaka = new Planet(
		"Mercury",
		color(220,176,154,255),
		3.3022e23,
		6,
		Vector2 (0, -5.7909100e10) + sol->getPosition(),
		Vector2(47.87e3,0)
		);
	m_space.addObject(kaka);

	//venus
	kaka = new Planet(
		"Venus",
		color(200,100,30,255),
		4.8685e24,
		8,
		Vector2 (-1.08208930e11, 0)+sol->getPosition(),
		Vector2(0,-3.502e4)
		);
	m_space.addObject(kaka);

	//temp
	player = new Player();
	player->setPlanet((Object*)kaka);
	m_game.addPlayer(player);

	//earth
	kaka = new Planet(
		"Earth",
		color(30,100,220,255),
		5.9736e24,
		8,
		Vector2 (1.495978875e11, 0)+sol->getPosition(),
		Vector2(0,2.9783e4)
		);
	m_space.addObject(kaka);

	//temp
	player = new Player();
	player->setPlanet((Object*)kaka);
	m_game.addPlayer(player);


	//mars
	kaka = new Planet(
		"Mars",
		color(180,156,120,255),
		6.4185e23,
		7,
		Vector2 (0, 2.27939100e11)+sol->getPosition(),
		Vector2(-2.4077e4,0)
		);
	m_space.addObject(kaka);    
}
